﻿/**
 * Created by ezgoing on 14/9/2014.
 */

"use strict";
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery'], factory);
    } else {
        factory(jQuery);
    }
}(function ($) {
    var cropbox = function (options, el) {
        var el = el || $(options.imageBox),
            obj =
            {
                state: {},
                ratio: 1,
                options: options,
                imageBox: el,
                thumbBox: el.find(options.thumbBox),
                spinner: el.find(options.spinner),
                image: new Image(),
                getDataURL: function () {
                    var width = this.thumbBox.width(),
                        height = this.thumbBox.height(),
                        canvas = document.createElement("canvas"),
                        dim = el.css('background-position').split(' '),
                        size = el.css('background-size').split(' '),
                        dx = parseInt(dim[0]) - el.width() / 2 + width / 2,
                        dy = parseInt(dim[1]) - el.height() / 2 + height / 2,
                        dw = parseInt(size[0]),
                        dh = parseInt(size[1]),
                        sh = parseInt(this.image.height),
                        sw = parseInt(this.image.width);

                    canvas.width = width;
                    canvas.height = height;
                    var context = canvas.getContext("2d");
                    console.log(this.image)
                    this.image.crossOrigin = "*";
                    context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
                    var imageData = canvas.toDataURL('image/jpeg');
                    return imageData;
                },
                getBlob: function () {
                    var imageData = this.getDataURL();
                    var b64 = imageData.replace('data:image/jpeg;base64,', '');
                    var binary = atob(b64);
                    var array = [];
                    for (var i = 0; i < binary.length; i++) {
                        array.push(binary.charCodeAt(i));
                    }
                    return new Blob([new Uint8Array(array)], { type: 'image/jpeg' });
                },
                zoomIn: function () {
                    this.ratio *= 1.1;
                    setBackground();
                },
                zoomOut: function () {
                    this.ratio *= 0.9;
                    setBackground();
                }
            },
            setBackground = function () {

                if (obj.ratio <= 200 / obj.image.width)
                    obj.ratio = 200 / obj.image.width;
                var w = parseInt(obj.image.width) * obj.ratio;
                var h = parseInt(obj.image.height) * obj.ratio;

                var pw = (el.width() - w) / 2;
                var ph = (el.height() - h) / 2;

                el.css({
                    'background-image': 'url(' + obj.image.src + ')',
                    'background-size': w + 'px ' + h + 'px',
                    'background-position': pw + 'px ' + ph + 'px',
                    'background-repeat': 'no-repeat'
                });
            },
            imgMouseDown = function (e) {
                e.preventDefault();
                e.stopImmediatePropagation();

                if (obj.image.src != options.imgSrc) {
                    obj.image.src = options.imgSrc;
                    obj.ratio = 1;
                }

                obj.state.dragable = true;
                obj.state.mouseX = e.clientX || e.pageX || e.originalEvent.touches[0].clientX;
                obj.state.mouseY = e.clientY || e.pageY || e.originalEvent.touches[0].clientY;

                if (e.originalEvent.touches.length >= 2) {

                    obj.state.pinchStartX0 = e.originalEvent.touches[0].clientX - obj.state.mouseX;
                    obj.state.pinchStartY0 = e.originalEvent.touches[0].clientY - obj.state.mouseY;
                    obj.state.pinchStartX1 = e.originalEvent.touches[1].clientX - obj.state.mouseX;
                    obj.state.pinchStartY1 = e.originalEvent.touches[1].clientY - obj.state.mouseY;
                    obj.state.Startjl = Math.sqrt(Math.pow((obj.state.pinchStartX1 - obj.state.pinchStartX0), 2) + Math.pow((obj.state.pinchStartY1 - obj.state.pinchStartY0), 2));

                }

            },
            imgMouseMove = function (e) {
                e.preventDefault();
                e.stopImmediatePropagation();

                if (obj.state.dragable) {

                    var x = (e.clientX || e.pageX || e.originalEvent.touches[0].clientX) - obj.state.mouseX;
                    var y = (e.clientY || e.pageY || e.originalEvent.touches[0].clientY) - obj.state.mouseY;

                    var bg = el.css('background-position').split(' ');

                    obj.state.bgX = x + parseInt(bg[0]);
                    obj.state.bgY = y + parseInt(bg[1]);

                    el.css('background-position', obj.state.bgX + 'px ' + obj.state.bgY + 'px');

                    if (e.originalEvent.touches.length >= 2) {
                        obj.state.pinchEndX0 = e.originalEvent.touches[0].clientX - obj.state.mouseX;
                        obj.state.pinchEndY0 = e.originalEvent.touches[0].clientY - obj.state.mouseY;
                        obj.state.pinchEndX1 = e.originalEvent.touches[1].clientX - obj.state.mouseX;
                        obj.state.pinchEndY1 = e.originalEvent.touches[1].clientY - obj.state.mouseY;
                        obj.state.Endjl = Math.sqrt(Math.pow((obj.state.pinchEndX1 - obj.state.pinchEndX0), 2) + Math.pow((obj.state.pinchEndY1 - obj.state.pinchEndY0), 2));
                        obj.ratio *= (obj.state.Endjl / obj.state.Startjl < 0 ? 1 : obj.state.Endjl / obj.state.Startjl);

                        setBackground();
                        obj.state.Startjl = obj.state.Endjl;
                    }

                    obj.state.mouseX = e.clientX || e.pageX || e.originalEvent.touches[0].clientX;
                    obj.state.mouseY = e.clientY || e.pageY || e.originalEvent.touches[0].clientY;

                }

            },
            imgMouseUp = function (e) {
                e.preventDefault();
                e.stopPropagation();
                obj.state.dragable = false;
            },
            zoomImage = function (e) {
                e.preventDefault();
                e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio *= 1.1 : obj.ratio *= 0.9;
                setBackground();
            }

        obj.image.src = options.imgSrc;
        obj.spinner.show();
        obj.image.onload = function () {

            obj.spinner.hide();
            setBackground();

            el.bind('touchstart mousedown MSPointerDown pointerdown', imgMouseDown);
            el.bind('touchmove mousemove MSPointerMove pointermove', imgMouseMove);
            el.bind('touchend mouseup MSPointerUp pointerup', imgMouseUp);
            el.bind('mousewheel DOMMouseScroll', zoomImage);

        };
        el.on('remove', function () {
            el.unbind('mouseup', imgMouseUp)
        });

        return obj;
    };

    jQuery.fn.cropbox = function (options) {
        return new cropbox(options, this);
    };
}));
